package com.pxmeta.app.controller.community;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.pxmeta.common.core.domain.AjaxResult;
import com.pxmeta.common.utils.SecurityUtils;
import com.pxmeta.common.utils.StringUtils;
import com.pxmeta.dynamic.entity.Mail;
import com.pxmeta.dynamic.entity.enums.MailInteractiveTypeEnum;
import com.pxmeta.dynamic.entity.enums.MailTypeEnum;
import com.pxmeta.dynamic.entity.vo.MailCountVO;
import com.pxmeta.dynamic.entity.vo.MailVO;
import com.pxmeta.dynamic.service.IMailService;
import com.pxmeta.user.entity.vo.UserVO;
import com.pxmeta.user.service.IUserFollowService;
import com.pxmeta.user.service.IUserService;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wcl
 * @since 2022-08-17
 */
@RestController
@RequestMapping("/dynamic/mail")
@Api(value = "站内信",tags = "站内信")
@RequiredArgsConstructor
public class MailController {

    private final IMailService mailService;
    private final IUserService userService;
    private final IUserFollowService userFollowService;


    @ApiOperation("获取站内信消息数量")
    @GetMapping("/getMailCount")
    @SaCheckLogin
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "circleId", value = "圈子id"),
            }
    )
    public AjaxResult<MailCountVO> getMailCount(@RequestParam Long circleId){
        Long userId = SecurityUtils.getUserId();
        long totalCount = mailService.getCount(userId,circleId,0);
        long interactCount = mailService.getCount(userId,circleId,1);
        long noticeCount = mailService.getCount(userId,circleId,2);
        MailCountVO vo = new MailCountVO();
        vo.setTotalCount(totalCount);
        vo.setInteractCount(interactCount);
        vo.setNoticeCount(noticeCount);
        return AjaxResult.success(vo);
    }

    @ApiOperation("获取站内信")
    @GetMapping("/getMailByCircleId")
    @SaCheckLogin
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "circleId", value = "圈子id"),
                    @ApiImplicitParam(name = "type", value = "类型：1互动，2通知"),
                    @ApiImplicitParam(name = "page", value = "页码"),
                    @ApiImplicitParam(name = "size", value = "每页记录数")
            }
    )
    public AjaxResult<List<MailVO>> getMailByCircleId(@RequestParam Integer type,
                                        @RequestParam Integer page,
                                        @RequestParam Integer size){
        Long userId = SecurityUtils.getUserId();
        LambdaQueryWrapper<Mail> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Mail::getTargetUserId,userId)
                .eq(Mail::getType, type)
                .orderByDesc(Mail::getCreateTime);
        List<Mail> list = mailService.page(new Page<>(page, size), wrapper).getRecords();

        if (CollectionUtil.isEmpty(list)){
            return AjaxResult.success(Lists.newArrayList());
        }

        list.forEach(l->l.setIsView(1));
        mailService.updateBatchById(list);
        if (MailTypeEnum.NOTICE.getType().equals(type)){
            List<MailVO> result = list.stream().map(l->{
                MailVO vo = new MailVO();
                vo.setContent(l.getContent());
                vo.setIsRead(l.getIsView()==1);
                vo.setTime(getNoticeTimeStr(l.getCreateTime()));
                return vo;
            }).collect(Collectors.toList());

            return AjaxResult.success(result);
        }

        List<Mail> userListMail = list.stream().filter(l -> MailInteractiveTypeEnum.LIKE.getType().equals(l.getInteractiveType())).collect(Collectors.toList());

        list.removeAll(userListMail);

        List<MailVO> result = Lists.newLinkedList();
        for (Mail mail : list) {
            MailVO mailVO = new MailVO();

            if (MailInteractiveTypeEnum.FOLLOW.getType().equals(mail.getInteractiveType())){
                boolean follow = userFollowService.isFollow(userId, mail.getUserId());
                mailVO.setIsFollow(follow);
            }

            mailVO.setCardContent(mail.getCardContent());
            mailVO.setInteractiveType(mail.getInteractiveType());
            String content = mail.getContent();
            if (StringUtils.isNotBlank(content) && content.length()>15){
                content = content.substring(0,15) + "...";
            }
            mailVO.setContent(content);
            List<UserVO> users = Lists.newLinkedList();
            Long mailUserId = mail.getUserId();
            UserVO userVO = userService.getUserVO(mailUserId);
            if (userVO == null){
                continue;
            }
            LocalDateTime createTime = mail.getCreateTime();
            mailVO.setDateTime(createTime);
            String operationTime = getTimeStr(createTime);
            mailVO.setTime(operationTime);
            userVO.setOperationTime(operationTime);
            users.add(userVO);
            mailVO.setUsers(users);
            mailVO.setTargetId(mail.getTargetId());
            mailVO.setIsRead(mail.getIsView()==1);
            result.add(mailVO);
        }

        //点赞站内信处理
        if (CollectionUtil.isNotEmpty(userListMail)){
            Set<Long> dynamicIds = userListMail.stream().map(Mail::getTargetId).collect(Collectors.toSet());
            for (Long dynamicId : dynamicIds) {
                Mail mail = userListMail.stream().filter(u -> u.getTargetId().equals(dynamicId)).findFirst().get();
                MailVO mailVO = new MailVO();
                List<Mail> mailList = userListMail.stream().filter(l -> l.getTargetId().equals(dynamicId)).collect(Collectors.toList());
                List<Long> userIds = mailList.stream().map(Mail::getUserId).collect(Collectors.toList());
                List<UserVO> userVOList = userService.getUserVOList(userIds);
                mailVO.setUsers(userVOList);
                for (UserVO userVO : userVOList) {
                    for (Mail userMail : mailList) {
                        if (userVO.getId().equals(userMail.getUserId())){
                            userVO.setOperationTime(getTimeStr(userMail.getCreateTime()));
                            break;
                        }
                    }
                }
                String content = mail.getContent();
                mailVO.setContent(content);
                mailVO.setCardContent(mail.getCardContent());
                mailVO.setInteractiveType(mail.getInteractiveType());
                LocalDateTime createTime = mail.getCreateTime();
                mailVO.setTime(getTimeStr(createTime));
                mailVO.setTargetId(mail.getTargetId());
                mailVO.setIsRead(mail.getIsView()==1);
                mailVO.setDateTime(createTime);
                result.add(mailVO);
            }
        }
        result.sort((o1, o2) -> {
            try {
                if (o1.getDateTime().isAfter(o2.getDateTime())){
                    return -1;
                }else {
                    return 1;
                }
            }catch (Exception ignored){
            }
            return 0;
        });

        return AjaxResult.success(result);
    }




    private String getNoticeTimeStr(LocalDateTime time){
        int month = time.getMonthValue();
        int day = time.getDayOfMonth();
        int hour = time.getHour();
        int second = time.getSecond();
        return String.format("%s-%s %s:%s",month,day,hour,second);
    }

    private String getTimeStr(LocalDateTime time){
        LocalDateTime now = LocalDateTime.now();
        int nowYear = now.getYear();
        int year = time.getYear();
        if (nowYear > year){
            int diffYear = nowYear - year;
            return diffYear + "年前";
        }


        int nowMonth = now.getMonth().getValue();
        int month = time.getMonth().getValue();
        if (month < nowMonth){
            int diffMonth = nowMonth - month;
            return diffMonth + "月前";
        }

        int nowDay = now.getDayOfMonth();
        int day = time.getDayOfMonth();

        if (nowDay > day){
            int diffDay = nowDay - day;
            int diffWeekDay = diffDay / 7;
            if (diffWeekDay > 1){
                return diffWeekDay + "周前";
            }
            return diffDay + "天前";
        }

        long l = Duration.between(time, now).toHours();
        if (l > 0){
            return l + "小时前";
        }

        long l1 = Duration.between(time, now).toMinutes();
        if (l1 > 0){
            return l1 + "分钟前";
        }
        return "刚刚";

    }

}
